<?php
def("amicitia/persistencia/daos/","DaoPareja");
def("amicitia/persistencia/daos/","ConexionBD");
def("amicitia/modelo/entidades/","Pareja");
def("amicitia/persistencia/excepciones/","IntegridadDatosException");

/**
 * Maneja todas las consideraciones de persistencia en MySql para con la
 * entidad Pareja.
 * 
 * @author Willy A. Kuster
 */
class DaoParejaMySql implements DaoPareja {

	const SELECT_PAREJA = "SELECT id, id_dador_fk, id_receptor_fk FROM pareja WHERE id=%s";
	const SELECT_EXISTE_PAREJA = "SELECT id FROM pareja WHERE id_dador_fk=%s AND id_receptor_fk=%s";
	const SELECT_PAREJAS_JUEGO = "SELECT a.id, a.id_dador_fk, a.id_receptor_fk FROM pareja a INNER JOIN juego_pareja b ON a.id=b.id_pareja_fk WHERE b.id_juego_fk=%s";
	const INSERT_PAREJA = "INSERT INTO pareja (id,id_dador_fk,id_receptor_fk) VALUES (%s,%s,%s)";
	const INSERT_JUEGO_PAREJA = "INSERT INTO juego_pareja (id_juego_fk,id_pareja_fk) VALUES (%s,%s)";
	const DELETE_PAREJA = "DELETE FROM pareja WHERE id=%s";

	private $conexion;

	public function __construct() {
		$this->conexion = ConexionBD::getConexionBD();
		//$this->conexion->conectar();
	}

	/**
	 * @see persistencia/daos/DaoPareja#obtenerPareja($id)
	 */
	public function obtenerPareja($id) {
		
		$id = $this->conexion->escaparCadena($id);
		$query = sprintf(self::SELECT_PAREJA,$id);
		$result = $this->conexion->seleccionar($query);

		if($obj = $result->fetch_object()){
			$pareja = $this->generarPareja($obj);

			$result->close();

			return $pareja;
		} else {
			return NULL;
		}
		
	}
	
	/**
	 * @see persistencia/daos/DaoPareja#obtenerParejasDeJuego($juego)
	 */
	function obtenerParejasDeJuego(Juego $juego) {
		$idJuego = $this->conexion->escaparCadena($juego->getId());
		$query = sprintf(self::SELECT_PAREJAS_JUEGO,$idJuego);
		$result = $this->conexion->seleccionar($query);
		
		while ($obj = $result->fetch_object()) {
			$parejas[$obj->id] = $this->generarPareja($obj);
		}
		$result->close();
		
		if(count($parejas)>0)
			return $parejas;
		else
			return NULL;
	}
	
	/**
	 * Crea un objeto Pareja a partir de un resultado de base de datos.
	 * 
	 * @param $obj
	 * 			Un objeto proveniente de la llamada $result->fetch_object().
	 * @return Pareja
	 * 			Un objeto Pareja.
	 */
	private function generarPareja($obj) {
		$pareja = new Pareja();
		$pareja->setId($obj->id);
		
		$fabricaDao = FabricaDao::obtenerFabrica();
		$daoPersona = $fabricaDao->obtenerDaoPersona();
		
		$pareja->setDador($daoPersona->obtenerPersona($obj->id_dador_fk));
		$pareja->setReceptor($daoPersona->obtenerPersona($obj->id_receptor_fk));
		
		return $pareja;
	}
	
	/**
	 * @see persistencia/daos/DaoPareja#guardarPareja($pareja)
	 */
	public function guardarPareja(Pareja $pareja) {
		
		$this->verificarPareja($pareja);
		
		$query = sprintf(self::SELECT_EXISTE_PAREJA,$pareja->getDador()->getId(),$pareja->getReceptor()->getId());
		$result = $this->conexion->seleccionar($query);
		
		if($obj = $result->fetch_object()) {
			return $obj->id;
		} else {
			$id = is_null($pareja->getId()) ? "NULL" : (int)$this->conexion->escaparCadena($pareja->getId());
			$id_dador_fk = (int)$this->conexion->escaparCadena($pareja->getDador()->getId());
			$id_receptor_fk = (int)$this->conexion->escaparCadena($pareja->getReceptor()->getId());
			
			$query = sprintf(self::INSERT_PAREJA,$id,$id_dador_fk,$id_receptor_fk);
			$id = $this->conexion->insertar($query);
			return $id;
		}
		
	}
	
	/**
	 * @see persistencia/daos/DaoPareja#guardarParejaEnJuego($pareja, $juego)
	 */
	public function guardarParejaEnJuego(Pareja $pareja,Juego $juego) {
		$id_pareja_fk = $this->guardarPareja($pareja);
		
		$id_juego_fk = (int)$this->conexion->escaparCadena($juego->getId());
		
		$query = sprintf(self::INSERT_JUEGO_PAREJA,$id_juego_fk,$id_pareja_fk);
		$this->conexion->insertar($query);
		
		return $id_pareja_fk;
	}
	
	/**
	 * @see persistencia/daos/DaoPareja#eliminarPareja($id)
	 */
	public function eliminarPareja($id) {
		
		$id = $this->conexion->escaparCadena($id);
		$query = sprintf(self::DELETE_PAREJA,$id);
		$afectados = $this->conexion->actualizarOEliminar($query);
		
		if ($afectados==1) {
			return true;
		} else {
			return false;
		}
		
	}
	
	/**
	 * Verifica la integridad del objeto Pareja que se pase por parámetro.
	 * 
	 * @param $pareja
	 * 			Un objeto Pareja.
	 */
	private function verificarPareja(Pareja $pareja) {
		if(is_null($pareja->getDador()))
			throw new IntegridadDatosException(get_class($pareja),"dador",$pareja->getDador());
		if(is_null($pareja->getDador()->getId()))
			throw new IntegridadDatosException(get_class($pareja->getDador()),"id",$pareja->getDador()->getId());
		if(is_null($pareja->getReceptor()))
			throw new IntegridadDatosException(get_class($pareja),"receptor",$pareja->getReceptor());
		if(is_null($pareja->getReceptor()->getId()))
			throw new IntegridadDatosException(get_class($pareja->getReceptor()),"id",$pareja->getReceptor()->getId());
	}
	
}
?>